// Copyright 2008-2009 BUGCOLLECT.COM
// Author: Remus Rusanu
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//                 http://bugcollect.com/terms
//

package com.bugcollect.log4j;

import com.bugcollect.ReportingManager;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;

/**
 * The BugCollect Appender.
 * Add this appender to your log4j configuration to enable
 * bug report colection at bugcollect.com<br/>
 * To enable this appender modify your log4j configuration file:
 * <pre>
 * {@code log4j.appender.A1 = com.bugcollect.log4j.Appender
log4j.appender.A1.applicationName = name
log4j.appender.A1.applicationPassword = password
log4j.rootLogger=ERROR, A1 
 * }
 * </pre>
 * where <code>name</code> and <code>password</code> are the credential
 * you created for this application with your bugcollect.com account.
 */
public class Appender extends AppenderSkeleton {

    private volatile ReportingManager reportingManager;

    private String applicationName;
    private String applicationPassword;

    /**
     * Sets the application name used to authenticate with bugcollect.com
     */
    public void setApplicationName(String value)
    {
        applicationName = value;
    }


    /**
     * Sets the password used to authenticate with bugcollect.com
     */
    public void setApplicationPassword(String value)
    {
        applicationPassword = value;
    }

    protected synchronized ReportingManager buildReportingManager()
    {
        ReportingManager manager = this.reportingManager;
        if (null == manager)
        {
            manager = new ReportingManager(
                applicationName
                , applicationPassword);
            reportingManager = manager;
        }
        return manager;
    }

    /**
     * Sets the <code>ReportingManager</code> object used to submit reports.
     * @param value
     */
    public void setReportingManager(ReportingManager value)
    {
        reportingManager = value;
    }

    /**
     * Gets the <code>ReportingManager</code> used to submit reports.
     * If not set explicitly,  the ReportingManager is constructed at the
     * moment the first report is submitted, or when this method invoked.
     * The default ReportingManager will use the application name and password
     * set on thsi Appender.
     */
    public ReportingManager getReportingManager()
    {
        return buildReportingManager();
    }

    /**
     * Submits the <code>LoggingEvent</code> to bugcollect.com
     * The report is constructed from the message and throwable information
     * in the <code>LoggingEvent</code>.
     */
    @Override
    protected void append(LoggingEvent event) {
        ReportingManager manager = buildReportingManager();
        ThrowableInformation throwableInfo = event.getThrowableInformation();
        manager.Submit(
                event.getRenderedMessage()
                , throwableInfo.getThrowable());
    }

    /**
     * log4j infrastructure method. This Appender doesn't do anything on close.
     */
    public void close() {
    }

    /**
     * log4j infrastructure method. The BugCollect appender does not require a layout.
     */
    public boolean requiresLayout() {
        return false;
    }

}
